/**
 * ExamSchedule.java.
 */
package rs.edu.fit.model;

import java.util.ArrayList;
import java.util.List;

public final class ExamSchedule {
	/** Exam that is conducting. */
	private Exam exam;
	/** Date and Time of the exam. */
	private DateAndTime dateAndTime;
	/** Assistent that supervise exam. */
	private Assistent assistent;
	/** List of students that takes this exam. */
	private List<Student> lStudents;

	/** Default constructor, can not be instantilized. */
	@SuppressWarnings("unused")
	private ExamSchedule() {

	}

	/**
	 * Working constructor; only exam is set, all data the rest data will be set
	 * later. It is commonly used when generate testing environment.
	 * 
	 * @param exam
	 *            that is scheduled.
	 */
	public ExamSchedule(Exam exam) {
		this.exam = exam;
		lStudents = new ArrayList<Student>();
	}

	/**
	 * Working constructor; without list of students( it is empty
	 * arraylist).
	 * 
	 * @param exam
	 *            that is holding.
	 * @param dateAndTime
	 *            date and time of the exam.
	 * @param assistent
	 *            that supervised exam.
	 */
	public ExamSchedule(Exam exam, DateAndTime dateAndTime, Assistent assistent) {
		super();
		this.exam = exam;
		this.dateAndTime = dateAndTime;
		this.assistent = assistent;
		lStudents = new ArrayList<Student>();
	}

	/**
	 * Working constructor; with all data.
	 * 
	 * @param exam
	 *            that is holding.
	 * @param dateAndTime
	 *            date and time of the exam.
	 * @param assistent
	 *            that supervised exam.
	 * @param lStudents
	 *            list of the student that are enrolled in this exam.
	 */
	public ExamSchedule(Exam exam, DateAndTime dateAndTime,
			Assistent assistent, List<Student> lStudents) {
		super();
		this.exam = exam;
		this.dateAndTime = dateAndTime;
		this.assistent = assistent;
		this.lStudents = lStudents;
	}
	
	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object o) {
		if (o instanceof ExamSchedule) {
			ExamSchedule examSchedule = (ExamSchedule) o;
			return this.exam.equals(examSchedule.getExam());
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		int result = 37;
		result += this.getExam().hashCode() + 27;

		return result;
	}

	/**
	 * Add student to the list of students. Data is only added
	 * if there is no same student in the list.
	 * 
	 * @param std
	 *            student that is adding.
	 * @return true if successfully added, false otherwise.
	 */
	public boolean addStudent(Student std) {
		if (!lStudents.contains(std)) {
			lStudents.add(std);
			return true;
		}
		return false;
	}

	/**
	 * Removing student from the list of the students. Data is only removed if
	 * there is same student in the list.
	 * 
	 * @param std
	 *            student that has been removing.
	 * @return true if removed, false otherwise.
	 */
	public boolean removeStudent(Student std) {
		if (lStudents.contains(std)) {
			lStudents.remove(std);
			return true;
		}
		return false;
	}
	
	/**
	 * Adding multiple students in the list of students. Rules like when adding
	 * single student.
	 * 
	 * @param lStudentsToAdd
	 *            list of the students to be added.
	 */
	public void addMultipleStudents(List<Student> lStudentsToAdd) {
		for (Student std : lStudentsToAdd) {
			addStudent(std);
		}
	}

	/**
	 * Removing multiple students from the list of the students. Rules like when
	 * removing single student.
	 *  
	 * @param lStudentsToRemove
	 *            list of the students to be removed.
	 */
	public void removeMultipleStudents(List<Student> lStudentsToRemove) {
		for (Student std : lStudentsToRemove) {
			removeStudent(std);
		}
	}

	/* Only getters, setters and toString from this point. */

	public final Exam getExam() {
		return exam;
	}

	public final void setExam(Exam exam) {
		this.exam = exam;
	}

	public final DateAndTime getDateAndTime() {
		return dateAndTime;
	}

	public final void setDateAndTime(DateAndTime dateAndTime) {
		this.dateAndTime = dateAndTime;
	}

	public final Assistent getAssistent() {
		return assistent;
	}

	public final void setAssistent(Assistent assistent) {
		this.assistent = assistent;
	}

	public final List<Student> getlStudents() {
		return lStudents;
	}

	public final void setlStudents(List<Student> lStudents) {
		this.lStudents = lStudents;
	}

	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "ExamSchedule [dateAndTime=" + dateAndTime + ", assistent="
				+ assistent + ", lStudents=" + lStudents + "]";
	}
}
